/**********************************************************************
 * 
 * Name: UpsertProductREST
 * Object: Product
 * Purpose: Upsert Product from NC
 * Requirement:
 * Author: kittylau (382376269@qq.com)
 * Create Date: 2016-12-31
 * Modify History: 
        2017-01-12 据最新需求文档做出修改,增加ts字段
 * 
 * Url: /services/apexrest/CRM/upsertProductREST
 * 接收的Json数据格式:
   {
    "data":[
        {
            "rowno":"行号",
            "invcode":"产品编码",
            "invname":"产品名称",
            "invspec":"规格",
            "invtype":"型号",
            "invshortname":"产品简称",
            "invmnecode":"助记码",
            "Invclcode":"存货分类编码",
            "Invclname":"存货分类名称",
            "jldw":"计量单位",
            "fjldw":"辅量单位",
            "taxitems":"税目",
            "cpx":"产品线",
            "vpp":"品牌",
            "vpzwh":"批准文号",
            "pzwhdate":"批准文号到期日",
            "sealflag":"封存标志",//Y/N
            "ts":"记录更新时间",
            "pk_invbasdoc":"存货基本档案主键"
            "own_corp":"分配公司"
        },
        {...}
        ]
   }
  返回的Json数据格式：
  {
    "result":"0 OR 1 , 1表示成功，0表示失败", 
    "result_msg":"成功为空，失败时为失败原因信息",
    "ts":"所有记录中,更新时间最近的那一条记录的更新时间"
  }
*************************************************************************/
@RestResource(urlMapping='/CRM/upsertProductREST/*')
global without sharing class UpsertProductREST {
    @HttpPost
    global static RestReturnMessage upsertProduct(List<ProductRestArgs> data) {
        RestReturnMessage msg = null;
        try{
            if(data.size() > 0){
                msg = doUpsertProduct(data);
            }else{
                throw new DmlException('没有数据');
            }
        }
        catch(Exception e){
            System.debug(LoggingLevel.INFO, '*** 错误信息: ' + e.getMessage() );
            System.debug(LoggingLevel.INFO, '*** 错误跟踪: ' + e.getStackTraceString());
            msg = Utils.getRestReturnMessage(false,e.getMessage() + ' - ' + e.getStackTraceString()+Datetime.valueOf(Utils.MIN_DATE_TIME),new List<Map<String ,String>>());
        }
        return msg;
    }

    //得到POST数据，完成Product数据的插入或更新
    global static RestReturnMessage doUpsertProduct (List<ProductRestArgs> data) {
        RestReturnMessage message = null;
        Datetime maxTs = Datetime.valueOf(Utils.MIN_DATE_TIME);
        System.debug(LoggingLevel.INFO, '*** Product Data FROM NC: ' + data);

        //保存传过来的Product编号集合
        List<String> proCodesList = new List<String>();
        Set<String> pronccodeSet = new Set<String>(); 
        Map<String,String> brands = new Map<String,String>();
        for(ProductRestArgs prod : data){
            if(prod.pk_invbasdoc != null && prod.pk_invbasdoc.length()>2){
                proCodesList.Add(prod.pk_invbasdoc);
                pronccodeSet.add(prod.invcode );
                if(!brands.containsKey(prod.vpp)){
                    brands.put(prod.vpp, '');
                }
                //如果当前记录的更新时间大于最大时间(maxTs)，则设置最大时间为当前记录时间
                Datetime dt = Utils.parseDatetime(prod.ts);
                if(dt > maxTs){
                    maxTs = dt;
                }
            }
        }
        //设置事务还原点，当操作失败时用来回滚
        SavePoint sp = Database.setSavePoint();
        try{
            // List<Brand__c> brandSave = new List<Brand__c>();

            /*2019-01-07
            List<Brand__c> brandList = [SELECT Id,Name FROM Brand__c WHERE Name IN :brands.keySet()];
              brands.clear();
            for(Brand__c br : brandList){
                brands.put(br.Name, br.Id);
            }*/
            // for(Brand__c br : brandList){
            //     brands.remove(br.Name);
            // }
            // if(brands.size() > 0){
            //     for(String br : brands.keySet()){
            //         Brand__c nbrand = new Brand__c();
            //         nbrand.Name = br;
            //         brandSave.add(nbrand);
            //     }
            //     Insert brandSave;
            // }
            //建立品牌名和Id的对应关系

          

            // for(Brand__c br : brandSave){
            //     brands.put(br.Name, br.Id);
            // }
              ///用来保存从表pk的记录集合
        	List<Map<String,String>> pkList = new List<Map<String,String>>();
            //用来保存或更新的列表集合
            List<Product__c> saveList = new List<Product__c>();
            //把已存在的Product保存在Map中以用来区别是新增或更新
            Map<String,Product__c> mapExistProds = new Map<String,Product__c>();
            Map<String,Product__c> mapExistProds2 = new Map<String,Product__c>();
            List<Product__c> existProducts = [SELECT Id,Name,NCinvshortname__c,SerialNo__c,NCCode__c,
                                        NCfjldw__c,NCtaxitems__c,TypeCode__c,NCvpzwh__c,NCpzwhdate__c,
                                        pk_invbasdoc__c,Company__c,
                                        Model__c,TypeName__c,Unit__c,Spec__c,ProductLineName__c,Brand__c   
                                   FROM Product__c 
                                   WHERE pk_invbasdoc__c IN :proCodesList or NCCode__c in: pronccodeSet];
            for(Product__c prod : existProducts){
                if(prod.pk_invbasdoc__c != null )mapExistProds.put(prod.pk_invbasdoc__c, prod);
                if(prod.NCCode__c != null )mapExistProds2.put(prod.NCCode__c, prod);
            }
            System.debug(LoggingLevel.INFO, '*** REST upsertProduct Method Exist Products: ' + mapExistProds.values());

            //新建或更新现存Product的字段值
            for(ProductRestArgs prod : data){
                if(prod.pk_invbasdoc != null){
                    Product__c itemForSave = null;
                    if(mapExistProds.containsKey(prod.pk_invbasdoc)){
                        itemForSave = mapExistProds.get(prod.pk_invbasdoc);
                    }else if(mapExistProds2.containsKey(prod.invcode)){
                        itemForSave = mapExistProds2.get(prod.invcode);
                    }else{
                        itemForSave = new Product__c();
                    }
                    //产品名称最大80个字符
                   /* String custN = '';
                    if(prod.invname != null){
                        custN = prod.invname;
                        if(custN.length() > 80){
                            custN = custN.substring(0,80);
                        }
                    }*/
                    itemForSave.NCCode__c = prod.invcode;//产品编码
                   // itemForSave.Name = custN;//产品名称
                    itemForSave.ProductName__c = prod.invname;
                    if(prod.invspec != null )itemForSave.Spec__c = prod.invspec;//规格
                    if(prod.invtype  != null )itemForSave.Model__c = prod.invtype;//型号
                    itemForSave.TypeName__c = prod.invclname;//存货分类名称
                    itemForSave.TypeCode__c = prod.invclcode;//存货分类编码
                    itemForSave.Unit__c = prod.jldw;//计量单位
                    itemForSave.ProductLineName__c = prod.cpx;//产品线
                    if(prod.vpp != null )itemForSave.Brand__c = prod.vpp;//品牌
                   // if(prod.vpp != null )itemForSave.CRMBrand__c = brands.containsKey(prod.vpp)?brands.get(prod.vpp):null;//CRM品牌
                    itemForSave.NCinvshortname__c = prod.invshortname;//产品简称
                    itemForSave.SerialNo__c = prod.invmnecode;//助记码
                    itemForSave.NCfjldw__c = prod.fjldw;//辅量单位
                    itemForSave.NCtaxitems__c = prod.taxitems;//税目
                    itemForSave.NCvpzwh__c = prod.vpzwh;//批准文号
                    itemForSave.sealflag__c = prod.sealflag;//封存标志 Y/N
                    itemForSave.pk_invbasdoc__c = prod.pk_invbasdoc;//存货基本档案主键
                    itemForSave.dr__c = prod.dr=='1'?true:false;//删除标记
                    itemForSave.Company__c = prod.own_corp;//产品公司
                    if(prod.zl != null )itemForSave.zl__c = prod.zl;
                    itemForSave.bggsjhdj__c = matchNumber(prod.bggsjhdj);
                    itemForSave.swjhdj__c = matchNumber(prod.swjhdj);
                    itemForSave.BudgetaryProducts__c = prod.docname ;
                    itemForSave.Vmakefactory__c = prod.vmakefactory;
                    itemForSave.SealCompany__c = prod.gssealflag ;
                    itemForSave.Install__c = prod.sfaz;

                    itemForSave.ApplicableInstrumentModel__c = prod.syjx == null ? null : prod.syjx.replaceAll(',', ';');
                    try{
                        itemForSave.NCpzwhdate__c = Date.valueOf(prod.pzwhdate);//批准文号到期日
                    }
                    catch(Exception e){
                        itemForSave.NCpzwhdate__c = null;//批准文号到期日
                    }
                        ///拼接返回的主表pk 和字表pk 
                    Map<String,String> pk = new Map<String,String>();
                    pk.put('mainpk',prod.pk_invbasdoc);
                    pk.put('sonpk','invbaseInfoPK');

                    pkList.add(pk);
                    saveList.add(itemForSave);
                }
            }
        
            Upsert saveList pk_invbasdoc__c ;
           // message = Utils.getRestReturnMessage(true,'',maxTs);
            message = Utils.getRestReturnMessage(true,'',pkList);
        }
        catch(Exception e) {
            System.debug(LoggingLevel.INFO, '*** 错误信息: ' + e.getMessage() );
            System.debug(LoggingLevel.INFO, '*** 错误跟踪: ' + e.getStackTraceString());
            //保存数据失败，回滚事务
            Database.rollback(sp);
            message =  Utils.getRestReturnMessage(false,e.getMessage() + ' - ' + e.getStackTraceString()+Datetime.valueOf(Utils.MIN_DATE_TIME),new List<Map<String ,String>>());
        }
        return message; 
    }
	private static Decimal matchNumber(String str){
        try{
            if(String.isNotBlank(str))str = str.replaceAll(',', '');
            Matcher m1 =  Pattern.compile('([0-9]([0-9]*)(\\.[0-9]+)?)|(^0$)').matcher(str);
            m1.find();
            
                String res = m1.group();
                return Decimal.valueOf(res);
            }catch(Exception e){
                return null;
            }
    }
    //根据NC提供的JSON结构来确定的Product字段集合
    global class ProductRestArgs {
        global String rowno; //行号
        global String invcode; //产品编码
        global String invname; //产品名称
        global String invspec; //规格
        global String invtype; //型号
        global String invshortname; //产品简称
        global String invmnecode; //助记码
        global String invclcode; //存货分类编码
        global String invclname; //存货分类名称
        global String jldw;//计量单位
        global String fjldw;//辅量单位
        global String taxitems;//税目
        global String cpx;//产品线
        global String vpp;//品牌
        global String vpzwh;//批准文号
        global String pzwhdate;//批准文号到期日
        global String sealflag;//封存标志 Y/N
        global String ts;//记录更新时间
        global String pk_invbasdoc;//存货基本档案主键
        //v1.5新增从表 nc那边传过来的数据里面多了一个dr字段，1或者0
        global String dr;
        global String own_corp;//产品所属公司
        
        
        global String zl ;//装量
        global String bggsjhdj ;//并购公司计划单价
        global String swjhdj ;//生物计划单价

        global String gssealflag ;//封存标记
        global String docname ;//预算大类
        global String vmakefactory ;//生产厂家
        global String sfaz ;//是否安装
        global String syjx ;//适用机型
	
    }
}